using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms.VisualStyles;
using at.jku.ssw.Coco;
using EnvDTE;


namespace Eclipse.VsCocoR.Imp.CodeGenerator
{
    [ComVisible(true),Guid("7E8510AC-C179-4cc3-937F-6F5809DF9899")]
    public class CocoRCSharpGenerator : BaseCodeGeneratorWithSite
    {
        static public OutputWindowPane OWp;
        public enum ErrorLevel
        {
            info,
            warning,
            error
        }
        public string _srcFile;


        override protected byte[] GenerateCode(string inputFileName, string inputFileContent)
        {
            object serviceObject = GetService(typeof(ProjectItem));
            Project containingProject;
            if (serviceObject != null)
            {
                containingProject = ((ProjectItem)serviceObject).ContainingProject;
                DTE dte = containingProject.DTE;
                Window win = dte.Windows.Item(Constants.vsWindowKindOutput);
                OutputWindow OW = (OutputWindow)win.Object;
                OWp = null;
                for (int i = 1; i <= OW.OutputWindowPanes.Count; i++)
                {
                    if (OW.OutputWindowPanes.Item(i).Name == "VsCoco")
                    {
                        OWp = OW.OutputWindowPanes.Item(i);
                        OWp.Clear();
                    }
                }
                if (OWp == null)
                {
                    OWp = OW.OutputWindowPanes.Add("VsCoco");
                }
            }
            _srcFile = inputFileName;

            try
            {
                MemoryStream stream = new MemoryStream();
                StreamWriter writer = new StreamWriter(stream);

                Scanner scanner = new Scanner(inputFileName);
                Parser parser = new Parser(scanner);
                string srcDir = Path.GetDirectoryName(inputFileName);
                string traceFileName = Path.Combine(srcDir, "trace.txt");
                parser.trace = new StreamWriter(new FileStream(traceFileName, FileMode.Create));
                parser.tab = new Tab(parser);
                parser.dfa = new DFA(parser);
                parser.dfa._gen = writer;
                parser.pgen = new ParserGen(parser);
                parser.pgen.gen = writer;

                parser.tab.srcName = inputFileName;
                parser.tab.srcDir = srcDir;
                parser.tab.nsName = FileNameSpace;
                parser.tab.frameDir = null;

                //if (ddtString != null) parser.tab.SetDDT(ddtString);

                parser.Parse();
                WriteLine(String.Format("{0} errors detected", parser.errors.count));
                parser.trace.Close();
                writer.Close();
                return stream.GetBuffer();
            }
            catch (Exception ex)
            {
                WriteError(0, 0, ErrorLevel.error, "Fatal error :" + ex);
                return System.Text.ASCIIEncoding.ASCII.GetBytes("// Fatal error : " + ex);
            }
        }
        

        public void WriteLine(string s)
        {
            OWp.OutputString(s);
            OWp.OutputString("\r\n");
        }


        public void WriteError(int lin, int col, ErrorLevel errorLevel,
            string errorMessage)
        {
            OWp.OutputString(string.Format("{0}({1},{2}): {3} {4}\r\n",
                new object[] {_srcFile, lin,col,
					(errorLevel== ErrorLevel.info?"":
					(errorLevel== ErrorLevel.warning?"Warning:":"Error"))
				,errorMessage}));
        }

    }
}
